package jwt

import (
	"context"
	"hertzjwt/model"
	"log"
	"time"

	"github.com/cloudwego/hertz/pkg/app"
	"github.com/hertz-contrib/jwt"
)

func NewJwtAuth() (*jwt.HertzJWTMiddleware, error) {
	// the jwt middleware
	authMiddleware, err := jwt.New(&jwt.HertzJWTMiddleware{
		Realm:       "test zone",
		Key:         []byte("secret key"),
		Timeout:     time.Hour,
		MaxRefresh:  time.Hour,
		IdentityKey: "username",
		PayloadFunc: func(data interface{}) jwt.MapClaims {
			if v, ok := data.(*model.User); ok {
				return jwt.MapClaims{
					"username": v.Username,
				}
			}
			return jwt.MapClaims{}
		},
		IdentityHandler: func(ctx context.Context, c *app.RequestContext) interface{} {
			claims := jwt.ExtractClaims(ctx, c)
			return &model.User{
				Username: claims["username"].(string),
			}
		},
		Authenticator: func(ctx context.Context, c *app.RequestContext) (interface{}, error) {
			var user model.User
			if err := c.BindAndValidate(&user); err != nil {
				return "", jwt.ErrMissingLoginValues
			}
			userID := user.Username
			password := user.Password

			if (userID == "admin" && password == "admin") || (userID == "test" && password == "test") {
				return &model.User{
					Username: userID,
					Email:    "xiaoxu@qq.com",
					Phone:    "1723649173",
				}, nil
			}

			return nil, jwt.ErrFailedAuthentication
		},
		Authorizator: func(data interface{}, ctx context.Context, c *app.RequestContext) bool {
			if v, ok := data.(*model.User); ok && v.Username == "admin" {
				return true
			}

			return false
		},
		Unauthorized: func(ctx context.Context, c *app.RequestContext, code int, message string) {
			c.JSON(code, map[string]interface{}{
				"code":    code,
				"message": message,
			})
		},
	})
	if err != nil {
		log.Fatal("JWT Error:" + err.Error())
	}
	err = authMiddleware.MiddlewareInit()
	if err != nil {
		return nil, err
	}
	return authMiddleware, nil
}
